package com.rzt.cft.utils;

import com.rzt.cft.dto.AbstractChildrenDto;
import org.apache.commons.lang3.StringUtils;

import java.util.List;

public class TreeUtil {

    /**
     * 递归树形数据(往下递归)
     *
     * @param source 数据源
     * @param pid    父级标识
     * @return 树状数据集合
     */
    public static <T extends AbstractChildrenDto> List<T> recursionList(List<T> source, String pid) {
        List<T> list = CustomUtil.where(source, x -> pid.equals(x.getParentId()));
        list = CustomUtil.orderBy(list, AbstractChildrenDto::getSort);
        list.forEach(x -> x.setChildren(recursionList(source, x.getId())));
        return list;
    }

    /**
     * 递归树形数据(往下递归)
     *
     * @param source 数据源
     * @param pid    父级标识
     * @return 数据集合
     */
    public static <T extends AbstractChildrenDto> List<T> recursionUnfoldList(List<T> source, String pid) {
        List<T> list = CustomUtil.where(source, x -> x.getParentId().equals(pid));
        List<String> idList = CustomUtil.select(list, AbstractChildrenDto::getId);
        idList.forEach(x -> list.addAll(recursionUnfoldList(source, x)));
        return list;
    }

    /**
     * 逆转递归树形数据(往上溯源)
     *
     * @param source 数据源
     * @param idList 标识集合
     * @param <T>
     * @return 数据列表
     */
    public static <T extends AbstractChildrenDto> List<T> reversalRecursionList(List<T> source, List<String> idList) {
        // 去重
        List<String> cidList = CustomUtil.distinct(idList);
        List<T> list = CustomUtil.where(source, x -> cidList.contains(x.getId()));

        // 上级菜单
        List<String> pidList = CustomUtil.select(list, AbstractChildrenDto::getParentId);
        // 排除 已存在项 && 无效项 && 已经是顶级项
        pidList = CustomUtil.where(pidList, x -> StringUtils.isNotBlank(x) && !"0".equals(x) && !cidList.contains(x));

        if (pidList.size() > 0)
            list.addAll(reversalRecursionList(source, pidList));
        return list;
    }

    /**
     * 获取递归标识集合
     *
     * @param source 数据源
     * @param pid    父级标识
     * @param <T>
     * @return
     */
    public static <T extends AbstractChildrenDto> List<String> getRecursionIdList(List<T> source, String pid) {
        List<T> list = CustomUtil.where(source, x -> x.getParentId().equals(pid));
        List<String> idList = CustomUtil.select(list, AbstractChildrenDto::getId);
        list.forEach(x -> idList.addAll(getRecursionIdList(source, x.getId())));
        return idList;
    }

}
